package com.bazhua.bazo.service.Impl;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectResult;
import com.bazhua.bazo.common.wxapplet.IWxAppletService;
import com.bazhua.bazo.common.wxapplet.model.WxAccountResponse;
import com.bazhua.bazo.common.wxapplet.model.WxAuthorizationResponse;
import com.bazhua.bazo.common.wxapplet.model.WxLoginRequest;
import com.bazhua.bazo.config.JwtConfig;
import com.bazhua.bazo.repository.entity.WechatUser;
import com.bazhua.bazo.repository.model.WeiXinOAuthToken;
import com.bazhua.bazo.repository.model.WxUser;
import com.bazhua.bazo.repository.model.result.CommonResult;
import com.bazhua.bazo.repository.model.result.ResultUtils;
import com.bazhua.bazo.service.ICheckUserService;
import com.bazhua.bazo.service.ICommonService;
import com.bazhua.bazo.service.IWechatUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

@Service
public class CommonServiceImpl implements ICommonService {

    @Value("${wechat.appid}")
    private String appId;

    @Value("${wechat.appsecret}")
    private String appSecret;

    @Value("${oss.OssUrl}")
    private String OssUrl;

    @Value("${oss.AccessKeyID}")
    private String AccessKeyID;

    @Value("${oss.AccessKeySecret}")
    private String AccessKeySecret;

    @Value("${oss.BucketName}")
    private String BucketName;

    @Value("${oss.BucketUrl}")
    private String BucketUrl;

    final IWxAppletService wxAppletService;

    final JwtConfig jwtConfig;

    final IWechatUserService wechatUserService;

    final ICheckUserService checkUserService;

    public CommonServiceImpl(IWxAppletService wxAppletService, JwtConfig jwtConfig, IWechatUserService wechatUserService, ICheckUserService checkUserService) {
        this.wxAppletService = wxAppletService;
        this.jwtConfig = jwtConfig;
        this.wechatUserService = wechatUserService;
        this.checkUserService = checkUserService;
    }

    @Override
    public CommonResult GetWeiXinOpenId(String code) throws IOException {
        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", appId, appSecret, code);
        String resultStr = HttpGetResult(url);
        WeiXinOAuthToken token = JSON.parseObject(resultStr, WeiXinOAuthToken.class);
        if (!StringUtils.isBlank(token.getOpenid()))
            return ResultUtils.ok(token);
        else
            return ResultUtils.error(80912, "获取失败:" + resultStr);
    }

    public CommonResult getWxUserInfoNew(WxAccountResponse wxAccountResponse) {
        WechatUser wechatUser = wechatUserService.findByOpenId(wxAccountResponse.getOpenid());
        // 如是新用户，注册一个用户
        if(wechatUser == null) {
            wechatUser = wechatUserService.register(wxAccountResponse);
        }else {
            wechatUser = wechatUserService.updateUser(wechatUser, wxAccountResponse);
        }
        WxUser wxUser = new WxUser();
        // JWT 返回自定义登陆态 Token
        String token = jwtConfig.createTokenByWxAccount(wechatUser.getId(), wxAccountResponse);
        wxUser.setToken(token);
        wxUser.setWechatUser(wechatUser);
        wxUser.setWxAccountResponse(wxAccountResponse);

        return ResultUtils.ok(wxUser);
    }

    @Override
    public CommonResult getWxUserInfo(WxLoginRequest request) {

        // 获取微信小程序授权数据
        WxAccountResponse wxAccountResponse = wxAppletService.wxUserLogin(request, false);

        WechatUser wechatUser = wechatUserService.findByOpenId(wxAccountResponse.getOpenid());
        // 如是新用户，注册一个用户
        if(wechatUser == null) {
            wechatUser = wechatUserService.register(wxAccountResponse);
        }

        WxUser wxUser = new WxUser();
        // JWT 返回自定义登陆态 Token
        String token = jwtConfig.createTokenByWxAccount(wechatUser.getId(), wxAccountResponse);
        wxUser.setToken(token);
        wxUser.setWechatUser(wechatUser);
        wxUser.setWxAccountResponse(wxAccountResponse);

        return ResultUtils.ok(wxUser);
    }

    @Override
    public CommonResult registerCheckUser(String openId, Long shopId) {
        return checkUserService.registerCheckUser(openId, shopId);
    }

    @Override
    public CommonResult wxUserAuthorization(String code) {
        WxAuthorizationResponse wxAuthorizationResponse = wxAppletService.wxUserAuthorization(code);
        return ResultUtils.ok(wxAuthorizationResponse);
    }

    @Override
    public CommonResult updateWxUserPhone(WxLoginRequest request) {
        // 获取微信小程序授权数据
        WxAccountResponse wxAccountResponse = wxAppletService.wxUserLogin(request, true);
        wechatUserService.updatePhone(wxAccountResponse.getOpenid(), wxAccountResponse.getPhone());
        return ResultUtils.ok(wxAccountResponse.getPhone());
    }

    @Override
    public CommonResult GetWXOAuthUserInfo(String accessToken, String openId) throws IOException {
        return null;
    }

    @Override
    public CommonResult upLoadPicture(String fileName, InputStream stream) {
        OSS ossClient = new OSSClientBuilder().build(OssUrl, AccessKeyID, AccessKeySecret);
        PutObjectResult result = ossClient.putObject(BucketName, fileName, stream);
        if (!StringUtils.isBlank(result.getETag())) {
            String fullUrl = BucketUrl + fileName;
            return ResultUtils.ok(fullUrl);
        } else
            return ResultUtils.error(90011, JSON.toJSONString(result));
    }

    private String HttpGetResult(String urlStr) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 返回结果-字节输入流转换成字符输入流，控制台输出字符
        BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    }
}
